home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.09 Sep 90 / Object1 Folder / CObject1Doc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-06  |  12.0 KB  |  518 lines  |  [TEXT/KAHL]

  1. /****
  2.  * CObject1Doc.c
  3.  *
  4.  *    Document methods for a typical application.
  5.  *
  6.  ****/
  7.  
  8. #include <Global.h>
  9. #include <Commands.h>
  10. #include <CApplication.h>
  11. #include <CBartender.h>
  12. #include <CDataFile.h>
  13. #include <CDecorator.h>
  14. #include <CDesktop.h>
  15. #include <CError.h>
  16. #include <CPanorama.h>
  17. #include <CScrollPane.h>
  18. #include "CObject1Doc.h"
  19. #include "CObject1Pane.h"
  20.  
  21.  
  22. #define    WINDObject1        500        /* Resource ID for WIND template */
  23.  
  24. extern    CApplication *gApplication;    /* The application */
  25. extern    CBartender    *gBartender;    /* The menu handling object */
  26. extern    CDecorator    *gDecorator;    /* Window dressing object    */
  27. extern    CDesktop    *gDesktop;        /* The enclosure for all windows */
  28. extern    CBureaucrat    *gGopher;        /* The current boss in the chain of command */
  29. extern    OSType        gSignature;        /* The application's signature */
  30. extern    CError        *gError;        /* The global error handler */
  31.  
  32. /***
  33.  * IObject1Doc
  34.  *
  35.  *    This is your document's initialization method.
  36.  *    If your document has its own instance variables, initialize
  37.  *    them here.
  38.  *    The least you need to do is invoke the default method.
  39.  *
  40.  ***/
  41.  
  42. void CObject1Doc::IObject1Doc(CBureaucrat *aSupervisor, Boolean printable)
  43.  
  44. {
  45.     CDocument::IDocument(aSupervisor, printable);
  46. }
  47.  
  48.  
  49. /***
  50.  * Dispose
  51.  *
  52.  *    This is your document's destruction method.
  53.  *    If you allocated memory in your initialization method
  54.  *    or opened temporary files, this is the place to release them.
  55.  *
  56.  *    Be sure to call the default method!
  57.  *
  58.  ***/
  59.  
  60. void CObject1Doc::Dispose()
  61.  
  62. {
  63.     inherited::Dispose();
  64. }
  65.  
  66.  
  67. /***
  68.  * DoCommand
  69.  *
  70.  *    This is the heart of your document.
  71.  *    In this method, you handle all the commands your document
  72.  *    deals with.
  73.  *
  74.  *    Be sure to call the default method to handle the standard
  75.  *    document commands: cmdClose, cmdSave, cmdSaveAs, cmdRevert,
  76.  *    cmdPageSetup, cmdPrint, and cmdUndo. To change the way these
  77.  *    commands are handled, override the appropriate methods instead
  78.  *    of handling them here.
  79.  *
  80.  ***/
  81.  
  82. void CObject1Doc::DoCommand(long theCommand)
  83.  
  84. {
  85.     switch (theCommand) {
  86.  
  87.         /* your document commands here */
  88.     
  89.         default:    inherited::DoCommand(theCommand);
  90.                     break;
  91.     }
  92. }
  93.  
  94. /***
  95.  * Activate
  96.  *
  97.  *    Your document is becoming active-- the front window.
  98.  *
  99.  *    In this method you can enable menu commands that apply only when
  100.  *    your document is active.
  101.  *
  102.  *    Be sure to call the default method to get the default behavior.
  103.  *    The default method enables these commands: cmdClose, cmdSaveAs,
  104.  *    cmdSave, cmdRevert, cmdPageSetup, cmdPrint, cmdUndo.
  105.  *
  106.  ***/
  107.  
  108. void CObject1Doc::Activate(void)
  109.  
  110. {
  111.     inherited::Activate();
  112. }
  113.  
  114.  
  115. /***
  116.  * Deactivate
  117.  *
  118.  *    Your document is becoming inactive-- another window is in front
  119.  *
  120.  *    In this method you can disable menu commands that don't apply
  121.  *    when your document isn't active.
  122.  *
  123.  *    Be sure to call the default method to get the default behavior.
  124.  *    The default method disables these commands: cmdClose, cmdSaveAs,
  125.  *    cmdSave, cmdRevert, cmdPageSetup, cmdPrint, cmdUndo.
  126.  *
  127.  ***/
  128.  
  129. void CObject1Doc::Deactivate(void)
  130.  
  131. {
  132.     inherited::Deactivate();
  133. }
  134.  
  135. /***
  136.  * NewFile
  137.  *
  138.  *    When the user chooses New from the File menu, the CreateDocument()
  139.  *    method in your Application class will send a newly created document
  140.  *    this message. This method needs to create a new window, ready to
  141.  *    work on a new document.
  142.  *
  143.  *    Since this method and the OpenFile() method share the code for creating
  144.  *    the window, you should use an auxiliary window-building method.
  145.  *
  146.  ***/
  147. void CObject1Doc::NewFile(void)
  148.  
  149. {
  150.         /**
  151.          **    BuildWindow() is the method that
  152.          **    does the work of creating a window.
  153.          **    It's parameter should be the data that
  154.          **    you want to display in the window.
  155.          **    Since this is a new window, there's nothing
  156.          **    to display.
  157.          **
  158.          **/
  159.  
  160.     BuildWindow(NULL);
  161.  
  162.         /**
  163.          **    Send the window a Select() message to make
  164.          **    it the active window.
  165.          **/
  166.     
  167.     itsWindow->Select();
  168. }
  169.  
  170.  
  171. /***
  172.  * OpenFile
  173.  *
  174.  *    When the user chooses Open… from the File menu, the OpenDocument()
  175.  *    method in your Application class will let the user choose a file
  176.  *    and then send a newly created document this message. The information
  177.  *    about the file is in the SFReply record.
  178.  *
  179.  *    In this method, you need to open the file and display its contents
  180.  *    in a window. This method uses the auxiliary window-building method.
  181.  *
  182.  ***/
  183.  
  184. void CObject1Doc::OpenFile(SFReply *macSFReply)
  185.  
  186. {
  187.     CDataFile    *theFile;
  188.     Handle        theData;
  189.     Str63        theName;
  190.     OSErr        theError;
  191.  
  192.         /**
  193.          ** Create a file and send it a SFSpecify()
  194.          **    message to set up the name, volume, and
  195.          **    directory.
  196.          **
  197.          **/
  198.  
  199.     theFile = new(CDataFile);
  200.     theFile->IDataFile();
  201.     theFile->SFSpecify(macSFReply);
  202.     
  203.         /**
  204.          **    Be sure to set the instance variable
  205.          **    so other methods can use the file if they
  206.          **    need to. This is especially important if
  207.          **    you leave the file open in this method.
  208.          **    If you close the file after reading it, you
  209.          **    should be sure to set itsFile to NULL.
  210.          **
  211.          **/
  212.  
  213.     itsFile = theFile;
  214.  
  215.         /**
  216.          **    Send the file an Open() message to
  217.          **    open it. You can use the ReadSome() or
  218.          **    ReadAll() methods to get the contents of the file.
  219.          **
  220.          **/
  221.  
  222.     theError = theFile->Open(fsRdWrPerm);
  223.  
  224.         /**
  225.          **    Check to see if we were able to open
  226.          **    the file. Send the error handler
  227.          **    a CheckOSError() message. If there was
  228.          **    an error, CheckOSError returns false
  229.          **    and reports the error in an alert.
  230.          **    The default error message displays the
  231.          **    error number.
  232.          **    You can use Estr resources to customize
  233.          **    the error message.
  234.          **
  235.          **    Note that we send ourselves a Dispose()
  236.          **    message. Since we're not going to open,
  237.          **    we should get rid of the object.
  238.          **/
  239.  
  240.     if (!gError->CheckOSError(theError)) {
  241.         Dispose();
  242.         return;
  243.     }
  244.  
  245.         /**
  246.          **    Make sure that the memory request to read
  247.          **    the data from the file doesn't use up any
  248.          **    of our rainy day fund and that the GrowMemory()
  249.          **    method (in the application) knows that it's OK
  250.          **    if we couldn't get enough memory.
  251.          **
  252.          **/
  253.  
  254.     gApplication->RequestMemory(FALSE, FALSE);
  255.     theFile->ReadAll(&theData);        /* ReadAll() creates the handle */
  256.  
  257.  
  258.         /**
  259.          **    If there isn't enough memory to open,
  260.          **    post the error (should be -108)
  261.          ** and get rid of ourselves.
  262.          **
  263.          **/
  264.  
  265.     if (theData == NULL) {
  266.         gError->CheckOSError(MemError());
  267.         Dispose();
  268.         return;
  269.     }
  270.  
  271.     
  272.     BuildWindow(theData);
  273.  
  274.         /**
  275.          **    In your application, you'll probably store
  276.          **    the data in some form as an instance variable
  277.          **    in your document class. For this example, there's
  278.          **    no need to save it, so we'll get rid of it.
  279.          **
  280.          **/
  281.  
  282.     DisposHandle(theData);
  283.  
  284.         /**
  285.          **    In this implementation, we leave the file
  286.          **    open. You might want to close it after
  287.          **    you've read in all the data.
  288.          **
  289.          **/
  290.  
  291.     itsFile->GetName(theName);
  292.     itsWindow->SetTitle(theName);
  293.     itsWindow->Select();            /* Don't forget to make the window active */
  294. }
  295.  
  296.  
  297.  
  298. /***
  299.  * BuildWindow
  300.  *
  301.  *    This is the auxiliary window-building method that the
  302.  *    NewFile() and OpenFile() methods use to create a window.
  303.  *
  304.  *    In this implementation, the argument is the data to display.
  305.  *
  306.  ***/
  307.  
  308. void CObject1Doc::BuildWindow (Handle theData)
  309.  
  310. {
  311.     CScrollPane        *theScrollPane;
  312.     CObject1Pane    *theMainPane;
  313.  
  314.         /**
  315.          **    First create the window and initialize
  316.          **    it. The first argument is the resource ID
  317.          **    of the window. The second argument specifies
  318.          **    whether the window is a floating window.
  319.          **    The third argument is the window's enclosure; it
  320.          **    should always be gDesktop. The last argument is
  321.          **    the window's supervisor in the Chain of Command;
  322.          **    it should always be the Document object.
  323.          **
  324.          **/
  325.  
  326.     itsWindow = new(CWindow);
  327.     itsWindow->IWindow(WINDObject1, FALSE, gDesktop, this);
  328.     
  329.         /**
  330.          **    After you create the window, you can use the
  331.          **    SetSizeRect() message to set the window’s maximum
  332.          **    and minimum size. Be sure to set the max & min
  333.          **    BEFORE you send a PlaceNewWindow() message to the
  334.          **    decorator.
  335.          **
  336.          ** The default minimum is 100 by 100 pixels. The
  337.          **    default maximum is the bounds of GrayRgn() (The
  338.          **    entire display area on all screens.)
  339.          **
  340.          **/
  341.  
  342.  
  343.     theScrollPane = new(CScrollPane);
  344.     
  345.         /**
  346.          **    You can initialize a scroll pane two ways:
  347.          **        1. You can specify all the values
  348.          **           right in your code, like this.
  349.          **        2. You can create a ScPn resource and
  350.          **           initialize the pane from the information
  351.          **           in the resource.
  352.          **
  353.          **/
  354.  
  355.     theScrollPane->IScrollPane(itsWindow, this, 10, 10, 0, 0,
  356.                                 sizELASTIC, sizELASTIC,
  357.                                 TRUE, TRUE, TRUE);
  358.  
  359.         /**
  360.          **    The FitToEnclFrame() method makes the
  361.          **    scroll pane be as large as its enclosure.
  362.          **    In this case, the enclosure is the window,
  363.          **    so the scroll pane will take up the entire
  364.          **    window.
  365.          **
  366.          **/
  367.  
  368.     theScrollPane->FitToEnclFrame(TRUE, TRUE);
  369.  
  370.  
  371.         /**
  372.          **    itsMainPane is the document's focus
  373.          **    of attention. Some of the standard
  374.          **    classes (particularly CPrinter) rely
  375.          **    on itsMainPane pointing to the main
  376.          **    pane of your window.
  377.          **
  378.          **    itsGopher specifies which object
  379.          **    should become the gopher. By default
  380.          **    the document becomes the gopher. It’s
  381.          **    likely that your main pane handles commands
  382.          **    so you’ll almost always want to set itsGopher
  383.          **    to point to the same object as itsMainPane.
  384.          **
  385.          **    Note that the main pane is the
  386.          **    panorama in the scroll pane and not
  387.          **    the scroll pane itself.
  388.          **
  389.          **/
  390.  
  391.     theMainPane = new(CObject1Pane);
  392.     itsMainPane = theMainPane;
  393.     itsGopher = theMainPane;
  394.     
  395.         /**    The FitToEnclosure() method makes the pane
  396.          **    fit inside the enclosure. The inside (or
  397.          **    interior) of a scroll pane is defined as
  398.          **    the area inside the scroll bars.
  399.          **/
  400.  
  401.     theMainPane->IObject1Pane(theScrollPane, this, 0, 0, 0, 0, sizELASTIC, sizELASTIC);
  402.     theMainPane->FitToEnclosure(TRUE, TRUE);
  403.  
  404.         /**
  405.          **    Send the scroll pane an InstallPanorama()
  406.          **    to associate our pane with the scroll pane.
  407.          **
  408.          **/
  409.  
  410.     theScrollPane->InstallPanorama(theMainPane);
  411.     
  412.         /**
  413.          **    The Decorator is a global object that takes care
  414.          **    of placing and sizing windows on the screen.
  415.          **    You don't have to use it.
  416.          **
  417.          **/
  418.  
  419.     gDecorator->PlaceNewWindow(itsWindow);
  420. }
  421.  
  422.  
  423. /***
  424.  * DoSave
  425.  *
  426.  *    This method handles what happens when the user chooses Save from the
  427.  *    File menu. This method should return TRUE if the file save was successful.
  428.  *    If there is no file associated with the document, you should send a
  429.  *    DoSaveFileAs() message.
  430.  *
  431.  ***/
  432.  
  433. Boolean CObject1Doc::DoSave(void)
  434.  
  435. {
  436.         /**
  437.          **    If you closed your file in your NewFile() method,
  438.          **    you'll need a different way than this to determine
  439.          **    if there's a file associated with your document.
  440.          **
  441.          **/
  442.  
  443.     if (itsFile == NULL)
  444.         return(DoSaveFileAs());
  445.     else {
  446.             
  447.         /**
  448.          **    In your application, this is where you'd
  449.          **    write out your file. if you left it open,
  450.          **    send the WriteSome() or WriteAll() mesages
  451.          **    to itsFile.
  452.          **
  453.          **/
  454.             
  455.         dirty = FALSE;                    /* Document is no longer dirty        */
  456.         gBartender->DisableCmd(cmdSave);
  457.         return(TRUE);                    /* Save was successful                */
  458.     }
  459. }
  460.  
  461.  
  462. /***
  463.  * DoSaveAs
  464.  *
  465.  *    This method handles what happens when the user chooses Save As… from
  466.  *    File menu. The default DoCommand() method for documents sends a DoSaveFileAs()
  467.  *    message which displays a standard put file dialog and sends this message.
  468.  *    The SFReply record contains all the information about the file you're about
  469.  *    to create.
  470.  *
  471.  ***/
  472.  
  473. Boolean CObject1Doc::DoSaveAs(SFReply *macSFReply)
  474.  
  475. {
  476.         /**
  477.          **    If there's a file associated with this document
  478.          **    already, close it. The Dispose() method for files
  479.          **    sends a Close() message to the file before releasing
  480.          **    its memory.
  481.          **
  482.          **/
  483.          
  484.     if (itsFile != NULL)
  485.         itsFile->Dispose();
  486.  
  487.  
  488.         /**
  489.          **    Create a new file, and then save it normally.
  490.          **
  491.          **/
  492.  
  493.     itsFile = new(CDataFile);
  494.     ((CDataFile *)itsFile)->IDataFile();
  495.     itsFile->SFSpecify(macSFReply);
  496.     itsFile->CreateNew(gSignature, 'TEXT');
  497.     itsFile->Open(fsRdWrPerm);
  498.     
  499.     itsWindow->SetTitle(macSFReply->fName);
  500.  
  501.     return( DoSave() );
  502. }
  503.  
  504.  
  505. /***
  506.  * DoRevert
  507.  *
  508.  *    If your application supports the Revert command, this method
  509.  *    should close the current file (without writing anything out)
  510.  *    and read the last saved version of the file.
  511.  *
  512.  ***/
  513.  
  514. void CObject1Doc::DoRevert(void)
  515.  
  516. {
  517. }
  518.